package com.party.admin.web.controller.course;

import com.party.admin.biz.activity.MemberActBizService;
import com.party.admin.biz.course.CourseBizService;
import com.party.admin.biz.file.ExcelExportService;
import com.party.admin.biz.file.FileBizService;
import com.party.admin.utils.excel.ExportExcel;
import com.party.admin.web.dto.AjaxResult;
import com.party.admin.web.dto.input.common.CommonInput;
import com.party.admin.web.dto.output.activity.ActivityOutput;
import com.party.admin.web.dto.output.activity.MemberActOutput;
import com.party.common.paging.Page;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.*;
import com.party.core.model.city.City;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.counterfoil.CounterfoilType;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.gatherForm.GatherProject;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberAct;
import com.party.core.model.member.MemberInfo;
import com.party.core.model.member.WithBuyer;
import com.party.core.service.activity.IActivityDetailService;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.activity.biz.ActivityDetailBizService;
import com.party.core.service.city.ICityService;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.counterfoil.ICounterfoilService;
import com.party.core.service.gatherForm.biz.GatherProjectBizService;
import com.party.core.service.member.IMemberActService;
import com.party.core.service.member.IMemberInfoService;
import com.party.core.service.member.IMemberService;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 课程活动控制器
 *
 * @author yifeng
 * @date 2018/10/23 0023
 * @time 上午 9:44
 */

@SuppressWarnings("all")
@Controller
@RequestMapping("activity/course")
public class CourseController {
    @Autowired
    private IActivityService activityService;
    @Autowired
    private IActivityDetailService activityDetailService;
    @Autowired
    private ActivityDetailBizService activityDetailBizService;
    @Autowired
    private ICounterfoilService counterfoilService;
    @Autowired
    private GatherProjectBizService gatherProjectBizService;
    @Autowired
    private ICityService cityService;
    @Autowired
    private CourseBizService courseBizService;
    @Autowired
    private IMemberActService memberActService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberInfoService memberInfoService;
    @Autowired
    private ExcelExportService excelExportService;
    @Autowired
    private FileBizService fileBizService;
    @Autowired
    private CosBizService cosBizService;
    @Autowired
    private MemberActBizService memberActBizService;

    Logger logger = LoggerFactory.getLogger(getClass());

    @RequestMapping("courseForm")
    public ModelAndView courseForm(String activityId) {
        ModelAndView mv = new ModelAndView("course/courseForm");
        if (StringUtils.isNotEmpty(activityId)) {
            Activity activity = activityService.get(activityId);
            if (activity == null) {
                mv.setViewName("error/unauthorized");
                return mv;
            }

            ActivityDetail activityDetail = activityDetailService.getByRefId(activity.getId());
            if (activityDetail != null) {
                activityDetailBizService.castToHTML(activityDetail);
            }

            Counterfoil t = new Counterfoil();
            t.setBusinessId(activityId);
            List<Counterfoil> counterfoils = counterfoilService.list(t);
            Counterfoil counterfoil = counterfoils.get(0);
            mv.addObject("counterfoil", counterfoil);

            mv.addObject("activity", activity);
            mv.addObject("activityDetail", activityDetail);

            mv.addObject("counterfoils", counterfoils);

            Map<String, Object> resultMap = gatherProjectBizService.getProjectBiz(activity.getId());
            mv.addAllObjects(resultMap);
        }
        City city = new City();
        city.setIsOpen(1);
        mv.addObject("citys", cityService.list(city));
        return mv;
    }

    @ResponseBody
    @RequestMapping("courseSave")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult courseSave(ActivityInput activityInput, Activity activity,
                                 BindingResult result, ActivityDetail activityDetail,
                                 GatherProject gatherProject) {
        try {
            // 数据验证
            if (result.hasErrors()) {
                List<ObjectError> allErros = result.getAllErrors();
                return AjaxResult.error(allErros.get(0).getDefaultMessage());
            }
            courseBizService.courseSave(activityInput, activity, activityDetail, gatherProject);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("课程保存异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("课程保存异常");
        }
    }

    /**
     * 课程列表
     *
     * @param activity    活动
     * @param commonInput 通用参数
     * @param page        分页
     * @param startBegin  开始时间-开始
     * @param startEnd    开始时间-结束
     * @return
     */
    @RequestMapping("courseList")
    public ModelAndView courseList(ActivityWithMemberPartner activity, CommonInput commonInput, Page page, String startBegin, String startEnd) {
        ModelAndView mv = new ModelAndView("course/courseList");
        Map<String, Object> params = CommonInput.appendParams(commonInput);
        activity.setDelFlag(BaseModel.DEL_FLAG_NORMAL);

        // 活动开始时间
        if (StringUtils.isNotEmpty(startBegin)) {
            params.put("startBegin", startBegin);
            mv.addObject("startBegin", startBegin);
        }
        if (StringUtils.isNotEmpty(startEnd)) {
            params.put("startEnd", startEnd);
            mv.addObject("startEnd", startEnd);
        }

        List<ActivityOutput> activityOutputs = courseBizService.courseList(activity, params, page);
        mv.addObject("activities", activityOutputs);
        mv.addObject("page", page);
        mv.addObject("activity", activity);
        mv.addObject("input", commonInput);
        mv.addObject("showAll", true);
        return mv;
    }

    @RequestMapping("listForDistribution")
    public ModelAndView listForDistribution(Activity activity, Page page, CommonInput commonInput) {
        page.setLimit(10);
        ModelAndView mv = new ModelAndView("course/distributionList");
        Map<String, Object> params = CommonInput.appendParams(commonInput);
        activity.setActivityType(ActivityType.COURSE.getCode());
        params.put("distributionType", DistributorRelationType.COURSE_DISTRIBUTION.getCode());
        List<DistributionActivity> activities = activityService.listForDistribution(activity, params, page);
        for (DistributionActivity input : activities) {
            String filePath = fileBizService.getUploadCIPath(input.getMember(), "course");

            String detailFileName = "detail_" + input.getId();
            String qrcodeUrl = cosBizService.getPreviewPictureUrl(filePath + detailFileName);
            input.setDetailQrCode(qrcodeUrl);
        }
        mv.addObject("activity", activity);
        mv.addObject("page", page);
        mv.addObject("activityList", activities);
        mv.addObject("input", commonInput);
        mv.addObject("showAll", false);
        return mv;
    }

    @RequestMapping(value = "applyList")
    public ModelAndView applyList(WithBuyer withBuyer, Page page, @RequestParam(required = false) String distributionId, CommonInput commonInput) {
        page.setLimit(20);
        withBuyer.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        ModelAndView modelAndView = new ModelAndView("course/applyList");
        Map<String, Object> params = CommonInput.appendParams(commonInput);
        params.put("distributionId", distributionId);
        params.put("activityType", ActivityType.COURSE.getCode());//加载课程类型的活动
        Map<Integer, String> checkStatus = ActStatus.convertMap();
        Activity activity = activityService.get(withBuyer.getActId());
        List<WithBuyer> withBuyerList = memberActService.withActivityList(withBuyer, params, page);

        if (null != params.get("startDate")) {
            commonInput.setCreateStart(params.get("startDate").toString().substring(0, 10));
        }
        if (null != params.get("endDate")) {
            commonInput.setCreateEnd(params.get("endDate").toString().substring(0, 10));
        }

        checkStatus.put(ActStatus.ACT_STATUS_AUDITING.getCode(), "审核中");
        checkStatus.put(ActStatus.ACT_STATUS_PAID.getCode(), "报名成功");
        modelAndView.addObject("page", page);
        modelAndView.addObject("input", commonInput);
        modelAndView.addObject("activity", activity);
        modelAndView.addObject("checkStatus", checkStatus);
        modelAndView.addObject("list", withBuyerList);
        return modelAndView;
    }


    /**
     * 课程报名导出
     * @param withBuyer
     * @param commonInput
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "applyExport", method = RequestMethod.POST)
    public AjaxResult applyExport(WithBuyer withBuyer, CommonInput commonInput, HttpServletResponse response) {
        try {
            String fileName = "课程报名人员.xlsx";
            Map<String, Object> params = CommonInput.appendParams(commonInput);
            params.put("activityType", ActivityType.COURSE.getCode());
            List<WithBuyer> withBuyerList = memberActService.withActivityList(withBuyer, params, null);
            List<MemberActOutput> memberActOutputs = LangUtils.transform(withBuyerList, input -> {
                MemberActOutput output = MemberActOutput.transform(input);
                MemberInfo memberInfo = memberInfoService.findByMemberId(input.getMemberId());
                if (null != memberInfo) {
                    output.setIdCard(memberInfo.getIdCard());
                }
                Activity activity = activityService.get(input.getActId());
                if (activity != null) {
                    output.setActivityTitle(activity.getTitle());
                }
                output.setCreateTime(input.getCreateDate());
                output.setCounterName(input.getCounterfoilName());
                output.setCounterPrice(input.getPayment());
                output.setCounterType(CounterfoilType.getValue(input.getCounterfoilType()));
                Member member = memberService.get(input.getMemberId());
                output.setMember(member);
                // 票据为线下付款
                if (CounterfoilType.TYPE_OFF_LINE.getCode().equals(input.getCounterfoilType())) {
                    // 已付款
                    if (MemberAct.PAY_STATUS_YES.equals(input.getPayStatus())) {
                        output.setCheckStatusName("报名成功，已支付");
                    } else if (MemberAct.PAY_STATUS_NO.equals(input.getPayStatus())) {
                        output.setCheckStatusName("报名成功，未支付");
                    }
                } else {
                    output.setCheckStatusName(ActStatus.getValue(input.getCheckStatus()));
                }
                if (null == input.getSignin() || input.getSignin().equals(YesNoStatus.NO.getCode())) {
                    output.setSignInName("未签到");
                } else {
                    output.setSignInName("已签到");
                }
                return output;
            });
            SXSSFWorkbook workbook = memberActBizService.exportExcel(memberActOutputs, withBuyer.getActId());
            String allPath = excelExportService.getExcelPath(fileName, "courseMemberAct", new ExportExcel(), workbook);
            return AjaxResult.success((Object) allPath);
        } catch (Exception e) {
            logger.error("课程报名人员导出异常：{}", e);
        }
        return AjaxResult.error("课程报名人员导出异常");
    }

}
